﻿using BST250301;
using BST250301.Views;
using BST250301TestStand.Models.Helpers;
using Google.Protobuf.WellKnownTypes;
using HslCommunication;
using HslCommunication.Profinet.Beckhoff;
using HslCommunication.Profinet.Omron;
using HslCommunication.Profinet.Siemens;
using HslCommunication.Secs.Types;
using MathNet.Numerics;
using MySqlX.XDevAPI;
using NPOI.SS.Formula.Functions;
using NPOI.XSSF.Streaming.Values;
using ScottPlot.Colormaps;
using SixLabors.ImageSharp.Metadata.Profiles.Iptc;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Log = BST250301TestStand.Models.Helpers.Log;

namespace BST250301TestStand.Models.Utils
{
    public class PLCConfig
    {
        public class ShowPLCStatusParm : EventArgs
        {
            public string PLCName { get; set; }
            public bool IsOnline { get; set; }
            /// <summary>
            /// 阶跃时的控制值
            /// </summary>
            public string SetpSetValue { get; set; }
            /// <summary>
            /// 循环油实际油温
            /// </summary>
            public float OilTempar { get; set; }
            /// <summary>
            /// 驱动端实际速度
            /// </summary>
            public float DriverSpeed { get; set; }
            /// <summary>
            /// 驱动端转矩
            /// </summary>
            public float DriverTorqu { get; set; }
            /// <summary>
            /// 加载端输出转矩
            /// </summary>
            public float LoadTorqut { get; set; }
            /// <summary>
            /// 循环油流量
            /// </summary>
            public float OilTraffic { get; set; }
            /// <summary>
            /// 驱动启动完成
            /// </summary>
            public bool isDriverStart { get; set; }
            /// <summary>
            /// 加载启动完成
            /// </summary>
            public bool isLoadStart { get; set; }
            /// <summary>
            /// 安全使能就绪-急停
            /// </summary>
            public bool isSafeStop { get; set; }
            /// <summary>
            /// 设备处于自动状态-允许启动
            /// </summary>
            public bool isAuto { get; set; }
            /// <summary>
            /// 驱动端对接完成
            /// </summary>
            public bool isDriverConnected { get; set; }
            /// <summary>
            /// 驱动端松开完成
            /// </summary>
            public bool isDriverDisconnected { get; set; }
            /// <summary>
            /// 加载端对接完成
            /// </summary>
            public bool isLoadConnected { get; set; }
            /// <summary>
            /// 加载端松开完成
            /// </summary>
            public bool isLoadDisconnected { get; set; }
            /// <summary>
            /// 加温已启动
            /// </summary>
            public bool isTempaAddStart { get; set; }
            /// <summary>
            /// 降温已启动
            /// </summary>
            public bool isTempaSubStart { get; set; }
            //Error_Word
            /// <summary>
            /// Error_Word
            /// </summary>
            public string errWord { get; set; }
        }
        public static event EventHandler<ShowPLCStatusParm> ShowPLCStatus;

        private static ShowPLCStatusParm _plcShow = new ShowPLCStatusParm();
        public string RemotePLCName { get; set; }
        public string RemotePLCtype { get; set; }
        public string RemotePLCaddress { get; set; }
        public int RemotePLCport { get; set; }
        public string RemotePLCslot { get; set; } = "0";
        public string RemotePLCHeardbeatValue { get; set; }

        public string RemotePLCHeardbeatType { get; set; }
        public string RemotePLCHeardbeatAddress { get; set; }
        public int RemotePLCHeardbeatPulse { get; set; }

        public int ConnectTimeOut { get; set; } = 3000;
        public int ReceiveTimeOut { get; set; } = 500;

        public string TargetAMSNetId { get; set; }
        public string SenderAMSNetId { get; set; }
        public bool UseTagCache { get; set; }
        public bool UseAutoAmsNetID { get; set; }
        public ushort AmsPort { get; set; }
        public bool IsAutoAMS { get; set; }
        public HeartBeatPLCData RemoteHeardbeat { get; set; }

        public BeckhoffAdsNet beckhoffAdsNet { get; set; }
        public SiemensS7Net siemensS7Net { get; set; }
        public OmronConnectedCipNet omronConnectedCipNet { get; set; }
        public OmronFinsNet omronFinsNet { get; set; }
        public OmronFinsUdpServer udpOmronClient { get; set; }
        public OmronCipNet omronCipNet { get; set; }
        internal static HslCommunication.Core.IReadWriteNet readWriteNet;
        public static bool IsConnectPLC = false;
        public int CountConnect = 0;

        #region PLC连接、心跳
        internal bool ConnectPLC(bool istest = false)
        {
            if (!Authorization.SetAuthorizationCode("8d367989-0ebb-43c1-b730-55c6af84784a"))
                MessageBox.Show("请联系管理员授权H");

            try
            {
                Log.ByTime($"开始连接PLC 【{RemotePLCaddress}:{RemotePLCport}】...");

                IsConnectPLC = SetPLCTypeConnectedPLCServer(RemotePLCtype);
                if (istest)
                    return IsConnectPLC;

                var ht = new PLCData
                {
                    PLCAdr = "DB1402.DBX0.0",
                    PLCType = "bool"
                };
                var remoteHeardbeat = new HeartBeatPLCData
                {
                    PLC = ht,
                    Pules = 500,
                };
                HeatBeatWrite(remoteHeardbeat);

                Log.ByTime($"ConnectPLC {RemotePLCName} ：{IsConnectPLC}");

                ht = new PLCData
                {
                    PLCAdr = "DB1403.DBX0.0",
                    PLCType = "bool"
                };
                remoteHeardbeat = new HeartBeatPLCData
                {
                    PLC = ht,
                    Pules = 500,
                };
                HeatBeatRead(remoteHeardbeat);
                ReadStatus();
                return IsConnectPLC;
            }
            catch (Exception)
            {
            }
            return false;
        }
        private bool SetPLCTypeConnectedPLCServer(string plctype)
        {
            try
            {
                if (plctype == null) return false;
                readWriteNet = null;
                plctype = plctype.ToUpper();
                OperateResult ret = null;
                switch (plctype)
                {
                    case "BECKHOFFADSNET":
                        beckhoffAdsNet = new BeckhoffAdsNet(RemotePLCaddress, RemotePLCport);
                        //beckhoffAdsNet.IpAddress = JsonConfigHelper.GetConfig(plcConfigStr, "终端IP");
                        //beckhoffAdsNet.Port = int.Parse(JsonConfigHelper.GetConfig(plcConfigStr, "终端Port"));
                        beckhoffAdsNet.ConnectTimeOut = ConnectTimeOut;
                        beckhoffAdsNet.ReceiveTimeOut = ReceiveTimeOut;
                        beckhoffAdsNet.SetTargetAMSNetId(TargetAMSNetId);
                        beckhoffAdsNet.SetSenderAMSNetId(SenderAMSNetId);
                        beckhoffAdsNet.UseTagCache = true;
                        if (IsAutoAMS)
                        {
                            beckhoffAdsNet.UseAutoAmsNetID = UseAutoAmsNetID;
                            beckhoffAdsNet.AmsPort = AmsPort;
                        }
                        beckhoffAdsNet.SetPersistentConnection();
                        ret = beckhoffAdsNet.ConnectServer();
                        if (ret.IsSuccess)
                        {
                            readWriteNet = beckhoffAdsNet;
                            string temp = beckhoffAdsNet.GetTargetAMSNetId();
                        }
                        Log.ByTime($"PLCconfig设置为：BeckhoffAdsNet ret {ret.Message}");
                        break;
                    case "SMART":
                        siemensS7Net = new SiemensS7Net(SiemensPLCS.S200Smart, RemotePLCport.ToString());
                        siemensS7Net.Port = RemotePLCport;
                        siemensS7Net.IpAddress = RemotePLCaddress;
                        siemensS7Net.ConnectTimeOut = ConnectTimeOut;
                        siemensS7Net.ReceiveTimeOut = ReceiveTimeOut;
                        siemensS7Net.SetPersistentConnection();
                        ret = siemensS7Net.ConnectServer();
                        readWriteNet = siemensS7Net;

                        Log.ByTime($"PLCconfig设置为：siemensS7Net ret {ret.Message}");

                        break;
                    case "SIEMENSS7NETS1200"://SIEMENSS7NETS1200
                        siemensS7Net = new SiemensS7Net(SiemensPLCS.S1200, RemotePLCport.ToString());
                        siemensS7Net.Port = RemotePLCport;
                        siemensS7Net.IpAddress = RemotePLCaddress;
                        siemensS7Net.ConnectTimeOut = ConnectTimeOut;
                        siemensS7Net.ReceiveTimeOut = ReceiveTimeOut;
                        siemensS7Net.SetPersistentConnection();
                        ret = siemensS7Net.ConnectServer();
                        readWriteNet = siemensS7Net;

                        Log.ByTime($"PLCconfig设置为：siemensS7NetS1200 ret {ret.Message}");

                        break;
                    case "OMRON CONNECTEDCIPNET":
                        omronConnectedCipNet = new OmronConnectedCipNet(RemotePLCaddress, RemotePLCport);
                        omronConnectedCipNet.IpAddress = RemotePLCaddress;
                        omronConnectedCipNet.Port = RemotePLCport;
                        omronConnectedCipNet.ConnectTimeOut = ConnectTimeOut;
                        omronConnectedCipNet.ReceiveTimeOut = ReceiveTimeOut;
                        omronConnectedCipNet.SetPersistentConnection();
                        ret = omronConnectedCipNet.ConnectServer();
                        readWriteNet = omronConnectedCipNet;
                        Log.ByTime($"PLCconfig设置为：OmronConnectedCipNet ret {ret.Message}");

                        break;
                    case "OMRONCIPNET":

                        omronCipNet = new OmronCipNet(RemotePLCaddress, RemotePLCport);
                        omronCipNet.IpAddress = RemotePLCaddress;
                        omronCipNet.Port = RemotePLCport;
                        omronCipNet.Slot = 0;
                        omronCipNet.ConnectTimeOut = ConnectTimeOut;
                        omronCipNet.ReceiveTimeOut = ReceiveTimeOut;
                        omronCipNet.SetPersistentConnection();
                        ret = omronCipNet.ConnectServer();
                        readWriteNet = omronCipNet;
                        Log.ByTime($"PLCconfig设置为：OmronCipNet ret {ret.Message}");
                        break;
                    case "OMRONFINS":
                        omronFinsNet = new OmronFinsNet();
                        omronFinsNet.IpAddress = RemotePLCaddress;
                        omronFinsNet.Port = RemotePLCport;
                        omronFinsNet.DA2 = byte.Parse(RemotePLCslot);
                        omronFinsNet.ByteTransform.DataFormat = HslCommunication.Core.DataFormat.CDAB;
                        omronFinsNet.SetPersistentConnection();
                        ret = omronFinsNet.ConnectServer();
                        if (ret.IsSuccess)
                        {
                            readWriteNet = omronFinsNet;
                        }
                        Log.ByTime($"PLCconfig设置为：OMRONFINSNET ret {ret.Message}");
                        break;
                    //readWriteNet = omronFinsNet;
                    //return true;
                    case "TCP SOCKET":
                        udpOmronClient = new OmronFinsUdpServer();
                        udpOmronClient.Port = RemotePLCport;
                        readWriteNet = udpOmronClient;
                        Log.ByTime($"PLCconfig设置为：OmronFinsUdpServer");
                        return true;
                    default:
                        return false;
                }

                //PLCProcess.readWriteNet=readWriteNet;
                return ret.IsSuccess;
            }
            catch (Exception ex)
            {
                Log.ErrorByTime($"连接PLC时有错误发生，catch：{ex.Message}");
            }
            return false;
        }
        public bool DisconnectPLCServer()
        {
            try
            {
                OperateResult ret = siemensS7Net.ConnectClose();
                return ret.IsSuccess;
            }
            catch (Exception ex)
            {
                Log.ErrorByTime($"连接PLC时有错误发生，catch：{ex.Message}");
            }
            return false;
        }
        public void HeatBeatWrite(HeartBeatPLCData plcdata)
        {
            Task.Run(() =>
            {
                while (true)
                {
                    try
                    {
                        Thread.Sleep(plcdata.Pules);
                        var ret = readWriteNet.Write(plcdata.PLC.PLCAdr, true);
                        Thread.Sleep(plcdata.Pules);
                        ret = readWriteNet.Write(plcdata.PLC.PLCAdr, false);
                    }
                    catch (Exception ex)
                    {
                        Log.ErrorByTime($"发送终端心跳时,Address:{plcdata.PLC.PLCAdr},type:{plcdata.PLC.PLCType},value:{plcdata.ActiveValue1} 未成功 错误：{ex.Message}");
                    }
                }
            });

        }

        public void HeatBeatRead(HeartBeatPLCData plcdata)
        {
            bool lastvalue = false;
            Task.Run(() =>
            {
                while (true)
                {
                    try
                    {
                        Thread.Sleep(plcdata.Pules);

                        var result = ReadPLCWithType(plcdata.PLC.PLCAdr, plcdata.PLC.PLCType);
                        OperateResult<bool> readbool = readWriteNet.ReadBool(plcdata.PLC.PLCAdr);
                        if (readbool.IsSuccess)
                        {
                            if (lastvalue == readbool.Content)
                            {
                                CountConnect++;
                                if (CountConnect > 2)
                                {
                                    IsConnectPLC = false;
                                }
                            }
                            else
                            {
                                lastvalue = readbool.Content;
                                CountConnect = 0;
                                IsConnectPLC = true;
                            }
                        }
                        else
                        {
                            CountConnect++;
                            if (CountConnect > 2)
                            {
                                IsConnectPLC = false;
                            }
                        }
                        //_plcShow.PLCName = RemotePLCName;
                        //_plcShow.IsOnline = IsConnectPLC;
                        //ShowPLCStatus?.Invoke(this, _plcShow);
                    }
                    catch (Exception ex)
                    {
                        Log.ErrorByTime($"读取终端心跳时,Address:{plcdata.PLC.PLCAdr},type:{plcdata.PLC.PLCType}");
                    }
                }
            });

        }
        public void HeatBeatWrite()
        {
            try
            {
                Thread.Sleep(RemotePLCHeardbeatPulse);

                string ret = HeartbeatWritePLCAddressWithType(RemoteHeardbeat, RemoteHeardbeat.ActiveValue1);//RemotePLCHeardbeatAddress, RemotePLCHeardbeatValue, RemotePLCHeardbeatType);
                Thread.Sleep(RemotePLCHeardbeatPulse);

                ret = HeartbeatWritePLCAddressWithType(RemoteHeardbeat, RemoteHeardbeat.ActiveValue2);
                Thread.Sleep(RemotePLCHeardbeatPulse);

                if (ret != null && ret.Contains("成功"))
                {
                    //CountConnect = 0;
                    //IsConnectPLC = true;
                    //Thread.Sleep(RemotePLCHeardbeatPulse);
                    //HeartbeatWritePLCAddressWithType(RemoteHeardbeat, RemoteHeardbeat.ActiveValue2); //HeartbeatWritePLCAddressWithType(RemotePLCHeardbeatAddress, RemotePLCHeardbeatValue2, RemotePLCHeardbeatType);
                }
                else if (ret == null || !ret.Contains("成功"))
                {
                    //Log.ErrorByTime($"发送终端心跳时,Address:{RemotePLCHeardbeatAddress},type:{RemotePLCHeardbeatType},value:{RemotePLCHeardbeatValue} 未成功");

                    //CountConnect++;
                    //if (CountConnect > 3)
                    //{
                    //    IsConnectPLC = false;
                    //}
                }
            }
            catch (Exception ex)
            {
                Log.ErrorByTime($"发送终端心跳时,Address:{RemotePLCHeardbeatAddress},type:{RemotePLCHeardbeatType},v:{RemotePLCHeardbeatValue} 错误：{ex.Message}");
            }
        }
        #endregion

        #region PLC交互
        public void ReadStatus()
        {
            Task.Run(() =>
            {
                while (true)
                {
                    try
                    {
                        Task.Delay(10);
#if DEBUG
                        _plcShow.IsOnline = true;
                        _plcShow.OilTempar = new Random().Next(-30, 90);
                        _plcShow.DriverSpeed = new Random().Next(10, 2200);
                        _plcShow.DriverTorqu = new Random().Next(2200, 7000);
                        _plcShow.LoadTorqut = new Random().Next(3000, 8000);
                        _plcShow.OilTraffic = new Random().Next(20, 90);
                        ShowPLCStatus?.Invoke(this, _plcShow);
                        continue;
#else

                      

                        //var oilttt = GetTestM100();
                        //_plcShow.OilTempar = oilttt;
                        //_plcShow.SetpSetValue = "";
                        //_plcShow.errWord = "离线啦";
                        //ShowPLCStatus?.Invoke(this, _plcShow);
                        //continue;

                        var oil = GetPLCOilTempa();
                        var oiltraffic = GetPLCOilTraffic();

                        var driverspeed = GetPLCDriverSpeed();
                        var drivertorquet = GetPLCDriverTorquet();
                        var loadtorquet = GetPLCLoadTorquet();

                        var ret = GetPLCItem0();
                        if (ret != null && ret.Length > 2)
                        {
                            _plcShow.isDriverStart = DataTranslate.GetBit(ret[0], 1);
                            _plcShow.isLoadStart = DataTranslate.GetBit(ret[0], 2);
                            _plcShow.isSafeStop = DataTranslate.GetBit(ret[0], 3);
                            _plcShow.isAuto = DataTranslate.GetBit(ret[0], 4);
                            _plcShow.isDriverConnected = DataTranslate.GetBit(ret[0], 5);
                            _plcShow.isDriverDisconnected = DataTranslate.GetBit(ret[0], 6);
                            _plcShow.isLoadConnected = DataTranslate.GetBit(ret[0], 7);
                            _plcShow.isLoadDisconnected = DataTranslate.GetBit(ret[1], 0);
                            _plcShow.isTempaAddStart = DataTranslate.GetBit(ret[1], 1);
                            _plcShow.isTempaSubStart = DataTranslate.GetBit(ret[1], 2);
                        }
                        else
                        {
                            var driverisstart = GetPLCDriverSuccess();
                            var loadisstart = GetPLCLoadSuccess();
                            var issafestop = GetPLCSafeStop();
                            var isauto = GetPLCAuto();
                            var isdriverconnected = GetPLCDriverConnected();
                            var isdriverdisconnected = GetPLCDriverDisconnected();
                            var isloadconnected = GetPLCLoadConnectSuccess();
                            var isloaddisconnected = GetPLCLoadDisconnectSuccess();
                            var istempadd = GetPLCTempAddSuccess();
                            var istempsub = GetPLCTempSubSuccess();
                            _plcShow.isDriverStart = driverisstart;
                            _plcShow.isLoadStart = loadisstart;
                            _plcShow.isSafeStop = issafestop;
                            _plcShow.isAuto = isauto;
                            _plcShow.isDriverConnected = isdriverconnected;
                            _plcShow.isDriverDisconnected = isdriverdisconnected;
                            _plcShow.isLoadConnected = isloadconnected;
                            _plcShow.isLoadDisconnected = isloaddisconnected;
                            _plcShow.isTempaAddStart = istempadd;
                            _plcShow.isTempaSubStart = istempsub;
                        }


                        var errword = GetPLCErrorWord();
                        if (errword != null)
                        {
                            string errmsg = string.Empty;
                            //安全使能未就绪/设备处于手动状态 - 无法启动////

                            if (errword[0] == 0x01)
                                errmsg += "安全使能未就绪;";
                            if (errword[1] == 0x01)
                                errmsg += "设备处于手动状态-无法启动;";
                            if (errword[2] == 0x01)
                                errmsg += "驱动端对接失败;";
                            if (errword[3] == 0x01)
                                errmsg += "加载端对接失败;";
                            if (errword[4] == 0x01)
                                errmsg += "驱动端转矩超载;";
                            if (errword[5] == 0x01)
                                errmsg += "其他停机报警;";
                            _plcShow.errWord = errmsg;
                        }
                        _plcShow.OilTempar = oil;
                        _plcShow.DriverSpeed = driverspeed;
                        _plcShow.DriverTorqu = drivertorquet;
                        _plcShow.LoadTorqut = loadtorquet;
                        _plcShow.OilTraffic = oiltraffic;
                        _plcShow.PLCName = RemotePLCName;
                        _plcShow.IsOnline = IsConnectPLC;

                        ShowPLCStatus?.Invoke(this, _plcShow);
#endif
                    }
                    catch (Exception ex)
                    {
                        Log.ErrorByTime($"读取PLC:{ex.Message}");
                    }
                }
            });
        }
        /// <summary>
        /// 驱动端启动
        /// </summary>
        public static bool SetPLCDriverStart(bool isstart)
        {
            _plcShow.SetpSetValue = isstart.ToString();
            PLCData plcstart = new PLCData
            {
                PLCAdr = "DB1402.DBX0.1",
                PLCType = "bool"
            };
            var ret = readWriteNet.Write(plcstart.PLCAdr, isstart);
            return ret.IsSuccess;
        }

        /// <summary>
        /// 加载端启动
        /// </summary>
        public static bool SetPLCLoadStart(bool isstop)
        {
            _plcShow.SetpSetValue = isstop.ToString();

            var plcstop = new PLCData
            {
                PLCAdr = "DB1402.DBX0.2",
                PLCType = "bool"
            };
            var ret = readWriteNet.Write(plcstop.PLCAdr, isstop);
            return ret.IsSuccess;
        }
        /// <summary>
        /// D档-前进
        /// </summary>
        /// <param name="isstop"></param>
        /// <returns></returns>
        public static bool SetPLCD(bool isstop)
        {
            _plcShow.SetpSetValue = isstop.ToString();

            var plcstop = new PLCData
            {
                PLCAdr = "DB1402.DBX0.3",
                PLCType = "bool"
            };
            var ret = readWriteNet.Write(plcstop.PLCAdr, isstop);
            return ret.IsSuccess;
        }
        /// <summary>
        /// R档-后退
        /// </summary>
        /// <param name="isstop"></param>
        /// <returns></returns>
        public static bool SetPLCR(bool isstop)
        {
            _plcShow.SetpSetValue = isstop.ToString();
            var plcstop = new PLCData
            {
                PLCAdr = "DB1402.DBX0.4",
                PLCType = "bool"
            };
            var ret = readWriteNet.Write(plcstop.PLCAdr, isstop);
            return ret.IsSuccess;
        }
        /// <summary>
        /// 驱动端对接
        /// </summary>
        /// <param name="isstop"></param>
        /// <returns></returns>
        public static bool SetPLCDriverConnect(bool isstop)
        {
            _plcShow.SetpSetValue = isstop.ToString();
            var plcstop = new PLCData
            {
                PLCAdr = "DB1402.DBX0.5",
                PLCType = "bool"
            };
            var ret = readWriteNet.Write(plcstop.PLCAdr, isstop);
            return ret.IsSuccess;
        }
        /// <summary>
        /// 驱动端松开
        /// </summary>
        /// <param name="isstop"></param>
        /// <returns></returns>
        public static bool SetPLCDriverDisconnect(bool isstop)
        {
            _plcShow.SetpSetValue = isstop.ToString();
            var plcstop = new PLCData
            {
                PLCAdr = "DB1402.DBX0.6",
                PLCType = "bool"
            };
            var ret = readWriteNet.Write(plcstop.PLCAdr, isstop);
            return ret.IsSuccess;
        }
        /// <summary>
        /// 加载端对接
        /// </summary>
        /// <param name="isstop"></param>
        /// <returns></returns>
        public static bool SetPLCLoadConnect(bool isstop)
        {
            _plcShow.SetpSetValue = isstop.ToString();
            var plcstop = new PLCData
            {
                PLCAdr = "DB1402.DBX0.7",
                PLCType = "bool"
            };
            var ret = readWriteNet.Write(plcstop.PLCAdr, isstop);
            return ret.IsSuccess;
        }
        /// <summary>
        /// 加载端松开
        /// </summary>
        /// <param name="isstop"></param>
        /// <returns></returns>
        public static bool SetPLCLoadDisconnect(bool isstop)
        {
            _plcShow.SetpSetValue = isstop.ToString();
            var plcstop = new PLCData
            {
                PLCAdr = "DB1402.DBX1.0",
                PLCType = "bool"
            };
            var ret = readWriteNet.Write(plcstop.PLCAdr, isstop);
            return ret.IsSuccess;
        }
        /// <summary>
        ///加温启动
        /// </summary>
        /// <param name="isstop"></param>
        /// <returns></returns>
        public static bool SetPLCTempaAdd(bool isstop)
        {
            _plcShow.SetpSetValue = isstop.ToString();
            var plcstop = new PLCData
            {
                PLCAdr = "DB1402.DBX1.1",
                PLCType = "bool"
            };
            var ret = readWriteNet.Write(plcstop.PLCAdr, isstop);
            return ret.IsSuccess;
        }
        /// <summary>
        ///降温启动
        /// </summary>
        /// <param name="isstop"></param>
        /// <returns></returns>
        public static bool SetPLCTempaSub(bool isstop)
        {
            _plcShow.SetpSetValue = isstop.ToString();
            var plcstop = new PLCData
            {
                PLCAdr = "DB1402.DBX1.2",
                PLCType = "bool"
            };
            var ret = readWriteNet.Write(plcstop.PLCAdr, isstop);
            return ret.IsSuccess;
        }
        /// <summary>
        /// 循环油目标油温
        /// </summary>
        public static bool SetPLCOilTempa(float value)
        {
            _plcShow.SetpSetValue = value.ToString();
            var plcoil = new PLCData
            {
                PLCAdr = "DB1402.DBD10",
                PLCType = "float"
            };
            var ret = readWriteNet.Write(plcoil.PLCAdr, value);
            return ret.IsSuccess;
        }

        /// <summary>
        /// 设置速度，并检测实际速度是否到达设定值
        /// </summary>
        /// <param name="value"></param>
        /// <param name="isTestSpeed">是否检测到达设定值</param>
        /// <returns></returns>
        public static async Task<bool> SetPLCSpeed(float value, bool isTestSpeed)
        {
            _plcShow.SetpSetValue = value.ToString();

            var plcSpeed = new PLCData
            {
                PLCAdr = "DB1402.DBD14",
                PLCType = "float"
            };
            var ret = readWriteNet.Write(plcSpeed.PLCAdr, value);
            if (ret.IsSuccess)
            {
                if (!isTestSpeed)
                    return true;

                if (value == 0)//0不判断driver是否start
                {
                    return await GetPLCDriverSpeedBool(0);
                }

                if (_plcShow.isDriverStart)
                {
                    return await GetPLCDriverSpeedBool(value);
                }
                else
                {
                    await Task.Delay(100);
                    if (await SetGetDriverStart())
                    {
                        return await GetPLCDriverSpeedBool(value);
                    }
                    return false;
                }
            }
            else
                return false;
        }
        /// <summary>
        /// 设置驱动端启动，并检测启动完成
        /// </summary>
        /// <returns></returns>
        public static async Task<bool> SetGetDriverStart()
        {
            if (!SetPLCDriverStart(true))
                return false;
            bool isC = false;
            await Task.Run(async () =>
            {
                int waitS = 30;
                while (waitS > 0)
                {
                    waitS--;
                    await Task.Delay(100);
                    if (GetPLCDriverSuccess())
                    {
                        isC = true;
                        break;
                    }
                }
            });
            return isC;
        }
        /// <summary>
        /// 驱动端目标转速,并检测实际速度
        /// </summary>
        public static async Task<bool> SetGetPLCSpeedAndTestSpeed(float setvalue)
        {
            bool isSpeed = false;
            _plcShow.SetpSetValue = setvalue.ToString();
            return await SetPLCSpeed(setvalue, true);
        }
        /// <summary>
        /// 加载端目标转矩
        /// </summary>
        public static bool SetPLCTorque(float value)
        {
            _plcShow.SetpSetValue = value.ToString();
            var plctTorquet = new PLCData
            {
                PLCAdr = "DB1402.DBD18",
                PLCType = "float"
            };

            var ret = readWriteNet.Write(plctTorquet.PLCAdr, value);
            return ret.IsSuccess;
        }
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        public static float GetTestM100()
        {
            var plcOilTempa = new PLCData
            {
                PLCAdr = "M100",
                PLCType = "float"
            };

            var ret = readWriteNet.ReadFloat(plcOilTempa.PLCAdr);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return -1;
        }
        /// <summary>
        /// 获取bit长度10
        /// </summary>
        /// <returns></returns>
        public static byte[] GetPLCErrorWord()
        {
            var ret = readWriteNet.Read("DB1403.DBW2.0", 16);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return null;

        }
        /// <summary>
        /// 获取bit长度10
        /// </summary>
        /// <returns></returns>
        public static byte[] GetPLCItem0()
        {
            var ret = readWriteNet.Read("DB1403.DBX0.1", 10);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return null;

        }
        /// <summary>
        /// 驱动启动完成
        /// </summary>
        public static bool GetPLCDriverSuccess()
        {
            var plcStartSuccess = new PLCData
            {
                PLCAdr = "DB1403.DBX0.1",
                PLCType = "bool"
            };

            var ret = readWriteNet.ReadBool(plcStartSuccess.PLCAdr);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return false;
        }
        /// <summary>
        /// 加载启动完成
        /// </summary>
        /// <returns></returns>
        public static bool GetPLCLoadSuccess()
        {
            var plcStartSuccess = new PLCData
            {
                PLCAdr = "DB1403.DBX0.2",
                PLCType = "bool"
            };

            var ret = readWriteNet.ReadBool(plcStartSuccess.PLCAdr);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return false;
        }
        /// <summary>
        /// 安全使能就绪-急停
        /// </summary>
        /// <returns></returns>
        public static bool GetPLCSafeStop()
        {
            var plcStartSuccess = new PLCData
            {
                PLCAdr = "DB1403.DBX0.3",
                PLCType = "bool"
            };

            var ret = readWriteNet.ReadBool(plcStartSuccess.PLCAdr);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return false;
        }
        /// <summary>
        /// 设备处于自动状态-允许启动
        /// </summary>
        /// <returns></returns>
        public static bool GetPLCAuto()
        {
            var plcStartSuccess = new PLCData
            {
                PLCAdr = "DB1403.DBX0.4",
                PLCType = "bool"
            };

            var ret = readWriteNet.ReadBool(plcStartSuccess.PLCAdr);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return false;
        }
        /// <summary>
        /// 驱动端对接完成
        /// </summary>
        /// <returns></returns>
        public static bool GetPLCDriverConnected()
        {
            var plcStartSuccess = new PLCData
            {
                PLCAdr = "DB1403.DBX0.5",
                PLCType = "bool"
            };

            var ret = readWriteNet.ReadBool(plcStartSuccess.PLCAdr);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return false;
        }
        /// <summary>
        /// 驱动端松开完成
        /// </summary>
        /// <returns></returns>
        public static bool GetPLCDriverDisconnected()
        {
            var plcStartSuccess = new PLCData
            {
                PLCAdr = "DB1403.DBX0.6",
                PLCType = "bool"
            };

            var ret = readWriteNet.ReadBool(plcStartSuccess.PLCAdr);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return false;
        }
        /// <summary>
        /// 加载端对接完成
        /// </summary>
        /// <returns></returns>
        public static bool GetPLCLoadConnectSuccess()
        {
            var plcStartSuccess = new PLCData
            {
                PLCAdr = "DB1403.DBX0.7",
                PLCType = "bool"
            };

            var ret = readWriteNet.ReadBool(plcStartSuccess.PLCAdr);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return false;
        }
        /// <summary>
        /// 加载端松开完成
        /// </summary>
        /// <returns></returns>
        public static bool GetPLCLoadDisconnectSuccess()
        {
            var plcStartSuccess = new PLCData
            {
                PLCAdr = "DB1403.DBX1.0",
                PLCType = "bool"
            };

            var ret = readWriteNet.ReadBool(plcStartSuccess.PLCAdr);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return false;
        }
        /// <summary>
        /// 加温已启动
        /// </summary>
        /// <returns></returns>
        public static bool GetPLCTempAddSuccess()
        {
            var plcStartSuccess = new PLCData
            {
                PLCAdr = "DB1403.DBX1.1",
                PLCType = "bool"
            };

            var ret = readWriteNet.ReadBool(plcStartSuccess.PLCAdr);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return false;
        }
        /// <summary>
        /// 降温已启动
        /// </summary>
        /// <returns></returns>
        public static bool GetPLCTempSubSuccess()
        {
            var plcStartSuccess = new PLCData
            {
                PLCAdr = "DB1403.DBX1.2",
                PLCType = "bool"
            };

            var ret = readWriteNet.ReadBool(plcStartSuccess.PLCAdr);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return false;
        }
        /// <summary>
        /// Error_Word
        /// </summary>
        /// <returns></returns>
        public static byte[] GetPLCError_Word()
        {
            var plcStartSuccess = new PLCData
            {
                PLCAdr = "DB1403.DBW2",
                PLCType = "string"
            };

            var ret = readWriteNet.Read(plcStartSuccess.PLCAdr, 16);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return null;
        }


        /// <summary>
        /// 当前油温
        /// </summary>
        public static float GetPLCOilTempa()
        {
            var plcOilTempa = new PLCData
            {
                PLCAdr = "DB1403.DBD10",
                PLCType = "float"
            };

            var ret = readWriteNet.ReadFloat(plcOilTempa.PLCAdr);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return -1;
        }
        /// <summary>
        /// 当前发动机速度
        /// </summary>
        public static float GetPLCDriverSpeed()
        {
            var plcSpeed = new PLCData
            {
                PLCAdr = "DB1403.DBD14",
                PLCType = "float"
            };

            var ret = readWriteNet.ReadFloat(plcSpeed.PLCAdr);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return -1;
        }
        /// <summary>
        /// 获取当前发动机速度是否达到设定值
        /// </summary>
        /// <param name="setvalue"></param>
        /// <returns></returns>
        public static async Task<bool> GetPLCDriverSpeedBool(float setvalue)
        {
            bool isSpeed = false;
            int ws = 60;
            await Task.Run(async () =>
            {
                while (ws > 0)
                {
                    ws--;
                    await Task.Delay(500);
                    var speed = GetPLCDriverSpeed();
                    if (speed >= setvalue - 70 && speed <= setvalue + 70)
                    {
                        isSpeed = true;
                        break;
                    }
                }
            });
            return isSpeed;
        }
        /// <summary>
        /// 当前转矩
        /// </summary>
        public static float GetPLCLoadTorquet()
        {
            var plcTorquet = new PLCData
            {
                PLCAdr = "DB1403.DBD18",
                PLCType = "float"
            };

            var ret = readWriteNet.ReadFloat(plcTorquet.PLCAdr);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return -1;
        }
        /// <summary>
        /// 驱动端转矩
        /// </summary>
        /// <returns></returns>
        public static float GetPLCDriverTorquet()
        {
            var plcTorquet = new PLCData
            {
                PLCAdr = "DB1403.DBD22",
                PLCType = "float"
            };

            var ret = readWriteNet.ReadFloat(plcTorquet.PLCAdr);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return -1;
        }
        public static float GetPLCOilTraffic()
        {
            var plcoiltraffic = new PLCData
            {
                PLCAdr = "DB1403.DBD26",
                PLCType = "float"
            };

            var ret = readWriteNet.ReadFloat(plcoiltraffic.PLCAdr);
            if (ret.IsSuccess)
                return ret.Content;
            else
                return -1;
        }
        public static bool GetPLCSafe()
        {
            return (_plcShow.isSafeStop && IsConnectPLC);
        }


        #endregion

        public OperateResult<byte[]> ReadPLCGroup(string[] addarr, ushort[] len)
        {
            OperateResult<byte[]> read = null;
            try
            {
                for (int i = 0; i < 3; i++)
                {
                    switch (RemotePLCtype)
                    {
                        case "BECKHOFFADSNET":
                            read = beckhoffAdsNet.Read(addarr, len);
                            break;
                        case "SMART":
                            read = siemensS7Net.Read(addarr, len);
                            break;
                        case "OMRON CONNECTEDCIPNET":
                            read = omronConnectedCipNet.Read(addarr, len);
                            break;
                        case "OMRONCIPNET":
                            read = omronCipNet.Read(addarr);
                            break;
                        case "OMRONFINSNET":
                            read = omronFinsNet.Read(addarr[0], Convert.ToUInt16(len.Length));
                            break;
                        default:
                            break;
                    }
                    if (read != null && read.IsSuccess)
                    {
                        return read;
                    }
                    else if (read == null || !read.IsSuccess)
                    {
                        Thread.Sleep(30);
                        continue;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.ErrorByTime($"Read PLC Group error:catch:{ex.Message}");
            }
            return read;
        }
        public OperateResult<float[]> ReadPLCFloatArray(string addarr, string plctype, ushort len)
        {
            OperateResult<float[]> read = null;
            try
            {
                for (int i = 0; i < 3; i++)
                {
                    read = readWriteNet.ReadFloat(addarr, len);

                    if (read != null && read.IsSuccess)
                    {
                        return read;
                    }
                    else if (read == null || !read.IsSuccess)
                    {
                        Thread.Sleep(30);
                        continue;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.ErrorByTime($"Read PLC Float Array error:catch:{ex.Message}");
            }
            return read;
        }
        public OperateResult<short[]> ReadPLCShortArray(string addarr, string plctype, ushort len)
        {
            OperateResult<short[]> read = null;
            try
            {
                for (int i = 0; i < 3; i++)
                {
                    read = readWriteNet.ReadInt16(addarr, len);

                    if (read != null && read.IsSuccess)
                    {
                        return read;
                    }
                    else if (read == null || !read.IsSuccess)
                    {
                        Thread.Sleep(30);
                        continue;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.ErrorByTime($"Read PLC Float Array error:catch:{ex.Message}");
            }
            return read;
        }
        public OperateResult<ushort[]> ReadPLCUshortArray(string addarr, string plctype, ushort len)
        {
            OperateResult<ushort[]> read = null;
            try
            {
                for (int i = 0; i < 3; i++)
                {
                    read = readWriteNet.ReadUInt16(addarr, len);

                    if (read != null && read.IsSuccess)
                    {
                        return read;
                    }
                    else if (read == null || !read.IsSuccess)
                    {
                        Thread.Sleep(30);
                        continue;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.ErrorByTime($"Read PLC Float Array error:catch:{ex.Message}");
            }
            return read;
        }
        public OperateResult<int[]> ReadPLCIntArray(string addarr, string plctype, ushort len)
        {
            OperateResult<int[]> read = null;
            try
            {
                for (int i = 0; i < 3; i++)
                {
                    read = readWriteNet.ReadInt32(addarr, len);

                    if (read != null && read.IsSuccess)
                    {
                        return read;
                    }
                    else if (read == null || !read.IsSuccess)
                    {
                        Thread.Sleep(30);
                        continue;
                    }
                }
            }
            catch (Exception ex)
            {
                Log.ErrorByTime($"Read PLC Float Array error:catch:{ex.Message}");
            }
            return read;
        }

        public object ReadPLCWithType(string address, string addType)
        {
            object obj = null;
            if (address == null || addType == null)
                return null;
            address = address?.Trim();
            addType = addType?.Trim().ToUpper();
            try
            {
                bool readSuccess = false;
                int count = 3;
                //address = RepalceSpecialStr(address);//针对倍福=号
                while (!readSuccess && count > 0)
                {
                    count--;
                    //if (IsConnectPLC)
                    if (readWriteNet != null)
                    {

                        switch (addType)
                        {
                            case "STRING":
                                OperateResult<string> readstr = readWriteNet.ReadString(address, 128, Encoding.ASCII);
                                obj = readstr.IsSuccess ? readstr.Content : null;
                                readSuccess = readstr.IsSuccess;
                                break;
                            case "STRING去控制符":
                                OperateResult<string> readstrr = readWriteNet.ReadString(address, 128, Encoding.ASCII);
                                if (readstrr.IsSuccess)
                                {
                                    string result = readstrr.Content;
                                    if (result.Contains("\\"))
                                    {
                                        result = result.Split('\\')[0];
                                    }
                                    if (result.Contains("\r"))
                                    {
                                        result = result.Split('\r')[0];
                                    }
                                    if (result.Contains("\n"))
                                    {
                                        result = result.Split('\n')[0];
                                    }
                                    obj = result;// readstrr.IsSuccess ? readstrr.Content.TrimStart('\r').TrimStart('\n').TrimEnd('\r').TrimEnd('\n').TrimEnd() : null;
                                }
                                readSuccess = readstrr.IsSuccess;
                                break;
                            case "BOOL":
                                OperateResult<bool> readbool = readWriteNet.ReadBool(address);
                                obj = readbool.IsSuccess ? readbool.Content : false;
                                readSuccess = readbool.IsSuccess;
                                break;
                            case "DOUBLE":
                                OperateResult<double> readdouble = readWriteNet.ReadDouble(address);
                                obj = readdouble.IsSuccess ? readdouble.Content : 0;
                                readSuccess = readdouble.IsSuccess;
                                break;
                            case "FLOAT":
                                OperateResult<float> readfloat = readWriteNet.ReadFloat(address);
                                if (readfloat.IsSuccess)
                                    obj = readfloat.Content;
                                readSuccess = readfloat.IsSuccess;
                                break;
                            case "FLOAT_00"://保留2位整数，1为01，11为11
                                OperateResult<float> readfloat00 = readWriteNet.ReadFloat(address);
                                if (readfloat00.IsSuccess)
                                    obj = readfloat00.Content.ToString("00");
                                readSuccess = readfloat00.IsSuccess;
                                break;
                            case "FLOAT_000"://保留2位整数，1为01，11为11
                                OperateResult<float> readfloat000 = readWriteNet.ReadFloat(address);
                                if (readfloat000.IsSuccess)
                                    obj = readfloat000.Content.ToString("000");
                                readSuccess = readfloat000.IsSuccess;
                                break;
                            case "FLOAT_0000"://保留2位整数，1为01，11为11
                                OperateResult<float> readfloat0000 = readWriteNet.ReadFloat(address);
                                if (readfloat0000.IsSuccess)
                                    obj = readfloat0000.Content.ToString("0000");
                                readSuccess = readfloat0000.IsSuccess;
                                break;
                            case "INT":
                                OperateResult<int> readint = readWriteNet.ReadInt32(address);
                                OperateResult<bool> readbyte = readWriteNet.ReadBool(address);

                                if (readint.IsSuccess)
                                    obj = readint.Content;
                                readSuccess = readint.IsSuccess;
                                break;
                            case "INT16":
                                OperateResult<short> read16 = readWriteNet.ReadInt16(address);
                                if (read16.IsSuccess)
                                    obj = read16.Content;
                                readSuccess = read16.IsSuccess;
                                break;
                            case "USHORT":
                                OperateResult<ushort> readu16 = readWriteNet.ReadUInt16(address);
                                if (readu16.IsSuccess)
                                    obj = readu16.Content;
                                readSuccess = readu16.IsSuccess;
                                break;
                            case "SHORT":
                                OperateResult<short> readint16 = readWriteNet.ReadInt16(address);
                                if (readint16.IsSuccess)
                                    obj = readint16.Content;
                                readSuccess = readint16.IsSuccess;
                                break;
                            case "DATETIME":
                                OperateResult<DateTime> readdate = new OperateResult<DateTime>();
                                OperateResult<long> operateResult = readWriteNet.ReadInt64(address);
                                if (!operateResult.IsSuccess)
                                {
                                    readdate = OperateResult.CreateFailedResult<DateTime>(operateResult);
                                    readSuccess = operateResult.IsSuccess;
                                }
                                else
                                {
                                    long value = operateResult.Content / 100;
                                    readdate = OperateResult.CreateSuccessResult(new DateTime(1970, 1, 1).AddTicks(value));
                                    if (readdate.IsSuccess)
                                    {
                                        obj = readdate.Content.ToString();
                                        readSuccess = readdate.IsSuccess;
                                    }
                                }
                                break;

                            default:
                                readSuccess = true;
                                break;
                        }

                    }

                }

            }
            catch (Exception ex)
            {
                Log.ErrorByTime($"PLC Config 读取地址错误，{address} = {obj?.ToString()},catch :{ex.Message},is connect PLC:{IsConnectPLC}");
            }
            return obj;
        }
        /// <summary>
        /// 按照active值写入
        /// </summary>
        /// <param name="plcd"></param>
        /// <returns></returns>
        public string WritePLCData(PLCData plcd)
        {
            return WritePLCAdrWithType(plcd.PLCAdr, plcd.PLCLastValue, plcd.PLCType);
        }

        public string WritePLCAdrWithType(string plcaddress, string plctype, string plcvalue)
        {
            OperateResult ret = null;
            if (readWriteNet == null || plcaddress == null || plcaddress == "" || !IsConnectPLC)
                return null;
            try
            {
                if (plctype != null)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        plctype = plctype.Trim().ToUpper();
                        switch (plctype)
                        {
                            case "STRING":
                                ret = readWriteNet.Write(plcaddress, plcvalue, Encoding.ASCII);
                                if (ret.IsSuccess)
                                    return ret.Message;
                                break;
                            case "STRINGUTF8":
                                ret = readWriteNet.Write(plcaddress, plcvalue, Encoding.UTF8);
                                if (ret.IsSuccess)
                                    return ret.Message;
                                break;
                            case "BOOL":
                                ret = readWriteNet.Write(plcaddress, bool.Parse(plcvalue));
                                if (ret.IsSuccess)
                                    return ret.Message;
                                break;
                            case "DOUBLE":
                                ret = readWriteNet.Write(plcaddress, double.Parse(plcvalue));
                                if (ret.IsSuccess)
                                    return ret.Message;
                                break;
                            case "FLOAT":
                                ret = readWriteNet.Write(plcaddress, float.Parse(plcvalue));
                                if (ret.IsSuccess)
                                    return ret.Message;
                                break;
                            case "INT":
                                ret = readWriteNet.Write(plcaddress, int.Parse(plcvalue));
                                if (ret.IsSuccess)
                                    return ret.Message;
                                break;
                            case "INT16":
                                ret = readWriteNet.Write(plcaddress, short.Parse(plcvalue));
                                if (ret.IsSuccess)
                                    return ret.Message;
                                break;
                            case "DATETIME":
                                ret = readWriteNet.Write(plcaddress, plcvalue);
                                if (ret.IsSuccess)
                                    return ret.Message;
                                break;
                            case "SHORT":
                                ret = readWriteNet.Write(plcaddress, short.Parse(plcvalue));
                                if (ret.IsSuccess)
                                    return ret.Message;
                                break;
                            case "USHORT":
                                ret = readWriteNet.Write(plcaddress, ushort.Parse(plcvalue));
                                if (ret.IsSuccess)
                                    return ret.Message;
                                break;
                            default:
                                ret = readWriteNet.Write(plcaddress, plcvalue);
                                if (ret.IsSuccess)
                                    return ret.Message;
                                break;
                        }
                        if (ret.IsSuccess)
                            break;
                        else
                        {
                            Log.PLCByTime($"底层写入PLC失败，正在第{i + 1}次重试：{plcaddress}，{plcvalue}，{plctype}");
                            if (i >= 3)
                            {
                                string warnningMsg = $">>>警告：写入PLC {plcaddress} = {plcvalue}， {i + 1}次失败，请检查连接和配置";
                            }
                            Thread.Sleep(50);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                if (ret != null)
                    Log.PLCByTime($"底层写入PLC：{plcaddress}，{plcvalue}，{plctype}，isSuccess{ret.IsSuccess},Msg:{ret.Message}");
            }
            return null;
        }
        public string HeartbeatWritePLCAddressWithType(HeartBeatPLCData plcHeart, string activeValue)
        {
            OperateResult ret = null;
            try
            {
                if (readWriteNet != null && plcHeart != null && plcHeart.PLC != null && !string.IsNullOrEmpty(activeValue))
                {
                    plcHeart.PLC.PLCType = plcHeart.PLC.PLCType.Trim().ToUpper();
                    switch (plcHeart.PLC.PLCType)
                    {
                        case "STRING":
                            ret = readWriteNet.Write(plcHeart.PLC.PLCAdr, activeValue);
                            if (ret.IsSuccess)
                                return ret.Message;
                            break;
                        case "BOOL":
                            ret = readWriteNet.Write(plcHeart.PLC.PLCAdr, bool.Parse(activeValue));
                            //ret = await readWriteNet.WriteAsync(plcaddress, bool.Parse(plcvalue));

                            if (ret.IsSuccess)
                            {
                                return ret.Message;
                            }
                            break;
                        case "DOUBLE":
                            ret = readWriteNet.Write(plcHeart.PLC.PLCAdr, double.Parse(activeValue));
                            if (ret.IsSuccess)
                                return ret.Message;
                            break;
                        case "FLOAT":
                            ret = readWriteNet.Write(plcHeart.PLC.PLCAdr, float.Parse(activeValue));
                            if (ret.IsSuccess)
                                return ret.Message;
                            break;
                        case "INT":
                            ret = readWriteNet.Write(plcHeart.PLC.PLCAdr, int.Parse(activeValue));
                            if (ret.IsSuccess)
                                return ret.Message;
                            break;
                        case "INT16":
                            ret = readWriteNet.Write(plcHeart.PLC.PLCAdr, short.Parse(activeValue));
                            if (ret.IsSuccess)
                                return ret.Message;
                            break;
                        case "DATETIME":
                            ret = readWriteNet.Write(plcHeart.PLC.PLCAdr, activeValue);
                            if (ret.IsSuccess)
                                return ret.Message;
                            break;
                        case "SHORT":
                            ret = readWriteNet.Write(plcHeart.PLC.PLCAdr, short.Parse(activeValue));
                            if (ret.IsSuccess)
                                return ret.Message;
                            break;
                        default:
                            ret = readWriteNet.Write(plcHeart.PLC.PLCAdr, activeValue);
                            if (ret.IsSuccess)
                                return ret.Message;
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
            }
            return null;
        }




    }
    public class PLCData
    {
        public string PLCName { get; set; }
        public string PLCAdr { get; set; }
        public string PLCType { get; set; }
        public string PLCValue { get; set; }
        public string PLCDesc { get; set; }
        public ushort PLCLen { get; set; }
        public string PLCLastValue { get; set; }
    }
    public class HeartBeatPLCData
    {
        public PLCData PLC { get; set; }
        public int Pules { get; set; }
        public string ActiveValue1 { get; set; }
        public string ActiveValue2 { get; set; }
    }
}
